; MemoryAsm.asm
; Support routines for memory management infrastructure (GDT, LDT
;
;  Copyright 2006 Corey Tabaka
;
;  Licensed under the Apache License, Version 2.0 (the "License");
;  you may not use this file except in compliance with the License.
;  You may obtain a copy of the License at
;
;      http://www.apache.org/licenses/LICENSE-2.0
;
;  Unless required by applicable law or agreed to in writing, software
;  distributed under the License is distributed on an "AS IS" BASIS,
;  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;  See the License for the specific language governing permissions and
;  limitations under the License.
;

section .data

[extern _gdtr]				; exported by pm_system.asm
[extern _idtr]				; exported by pm_system.asm

section .text

[global _loadGDTR]
[global _loadIDTR]
[global _loadDS]
[global _loadFS]
[global _loadTR]
[global _loadCR3]
[global _getCR3]
[global _getESP]
[global _getCR2]
[global _enablePaging]
[global _invalidatePage]

bits 32

_loadGDTR:
	push ebp
	mov ebp,esp
	
	xor eax,eax
	mov eax,[ebp + 12]		; param short limit
	mov word [_gdtr],ax
	
	mov eax,[ebp + 8]		; param gde_t * gdt
	mov dword [_gdtr + 2],eax
	
	lgdt [_gdtr]
	
	leave
	ret

_loadIDTR:
	push ebp
	mov ebp,esp
	
	xor eax,eax
	mov eax,[ebp + 12]		; param short limit
	mov word [_idtr],ax
	
	mov eax,[ebp + 8]		; param gde_t * gdt
	mov dword [_idtr + 2],eax
	
	lidt [_idtr]
	
	leave
	ret

_loadTR:
	push ebp
	mov ebp,esp
	
	mov ax,[ebp + 8]
	ltr ax
	
	leave
	ret
	
_loadDS:
	push ebp
	mov ebp,esp
	
	mov ax,[ebp + 8]
	mov ds,ax
	
	leave
	ret

_loadFS:
	push ebp
	mov ebp,esp
	
	mov ax,[ebp + 8]
	mov fs,ax
	
	leave
	ret

; void load_CR3(page_entry_t *dir);
_loadCR3:
	push ebp
	mov ebp,esp
	
	mov eax,[ebp + 8]
	mov cr3,eax
	
	leave
	ret

_getCR3:
	mov eax,cr3
	
	ret

_getESP:
	push ebp
	mov ebp,esp
	
	mov eax,esp
	
	leave
	ret

_getCR2:
	push ebp
	mov ebp,esp
	
	mov eax,cr2
	
	leave
	ret

; void enablePaging(bool enable);
%define CR0_PAGING_ENABLE 0x80000000

_enablePaging:
	push ebp
	mov ebp,esp
	
	mov eax,cr0
	
	; check enable or disable
	cmp dword [ebp + 8],0
	je .disable
	
	mov ebx,CR0_PAGING_ENABLE
	or eax,ebx
	jmp .store

.disable:
	mov ebx,~CR0_PAGING_ENABLE
	and eax,ebx
	
.store:
	mov cr0,eax		; relaod cr0 with paging bit
	jmp .end		; short jump

.end:
	leave
	ret

_invalidatePage:
	mov eax,[esp + 4]
	invlpg [eax]
	
	ret
